使用 shared file list 在系统的登录项中是可见的。用户可以直接在面板上控制他们。(If you use this API, your login item can be disabled by the user, so any other application that communicates with it it should have reasonable fallback behavior in case the login item is disabled.) 原文还有一句大意是指这个API有隐患,所以在OS X 10.10系统上 API被大量Deprecated
下面具体介绍一下 这两种的实现
Adding Login Item Using the Service Management Framework
- (BOOL)isLaunchAtStartup { // See if the app is currently in LoginItems. LSSharedFileListItemRef itemRef = [self itemRefInLoginItems]; // Store away that boolean. BOOL isInList = itemRef != nil; // Release the reference if it exists. if (itemRef != nil) CFRelease(itemRef); return isInList; }
- (IBAction)toggleLaunchAtStartup:(id)sender { // Toggle the state. BOOL shouldBeToggled = ![self isLaunchAtStartup]; // Get the LoginItems list. LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); if (loginItemsRef == nil) return; if (shouldBeToggled) { // Add the app to the LoginItems list. CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL); if (itemRef) CFRelease(itemRef); [[self.statusMenu itemAtIndex:0] setTitle:@"取消开机自启动"]; } else { // Remove the app from the LoginItems list. LSSharedFileListItemRef itemRef = [self itemRefInLoginItems]; LSSharedFileListItemRemove(loginItemsRef,itemRef); if (itemRef != nil) CFRelease(itemRef); [[self.statusMenu itemAtIndex:0] setTitle:@"设置开机自启动"]; } CFRelease(loginItemsRef); }
- (LSSharedFileListItemRef)itemRefInLoginItems { LSSharedFileListItemRef res = nil; // Get the app's URL. NSURL *bundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; // Get the LoginItems list. LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); if (loginItemsRef == nil) return nil; // Iterate over the LoginItems. NSArray *loginItems = (__bridge NSArray *)LSSharedFileListCopySnapshot(loginItemsRef, nil); for (id item in loginItems) { LSSharedFileListItemRef itemRef = (__bridge LSSharedFileListItemRef)(item); CFURLRef itemURLRef; if (LSSharedFileListItemResolve(itemRef, 0, &itemURLRef, NULL) == noErr) { // Again, use toll-free bridging. NSURL *itemURL = (__bridge NSURL *)itemURLRef; if ([itemURL isEqual:bundleURL]) { res = itemRef; break; } } } // Retain the LoginItem reference. if (res != nil) CFRetain(res); CFRelease(loginItemsRef); CFRelease((__bridge CFTypeRef)(loginItems)); return res; }
In previous versions of OS X, it is possible to add login items by sending an Apple event, by using the CFPreferences API, and by manually editing a property list file. These approaches are deprecated.
If you need to maintain compatibility with versions of OS X prior to v10.5, the preferred approach is to use Apple events; for details, see LoginItemsAE. Using the CFPreferences API is an acceptable alternative. You should not directly edit the property list file on any version of OS X.